#ifndef CaptureDevice_HPP
#define CaptureDevice_HPP

#include <QObject>

#ifdef Q_OS_WIN32
#pragma comment(lib, "strmiids.lib")
#endif

struct FormatSize {
    int width;
    int height;
    int fps_numerator[64];
    int fps_denominator[64];
    int fps_count;
};

struct FormatsInfo {
    int         fmt;
    int         count;
    FormatSize  sizes[64];
    int         sizes_count;
    /* Colour Space Name */
    char        description[32];
};

#include <platform.hpp>
#ifdef USE_QOBJECT
#include <QThread>
#include <QObject>
#include <QMutex>
#endif

class CPCapCaptureThread;

class EXPORT_DLL CPCapDevice : public QObject
{
#ifdef USE_QOBJECT
    Q_OBJECT
#endif
public:
    CPCapDevice(const char *uid,
                const char *name,
                int pC,
                QObject *parent = 0);
    CPCapDevice(const char *uid,
                const char *name,
                int physical,
                int w,
                int h,
                int fmt,
                QObject *parent);

    ~CPCapDevice();
    /* Propiedades */
    int    nativeWidth() const;
    int    nativeHeight() const;
    int    getPhysicalConnection() const;

    /* Control del dispositivo */
    bool   isConnected() const;
    void   connectDevice();
    void   disconnectDevice();
    void   setResolution(int);

    /* Control de Salida */
    void   setBrightness(long value);
    void   setContrast(long value);
    void   setHue(long value);
    void   setSaturation(long value);
    void   setSharpness(long value);
    void   setGamma(long value);
    void   setGain(long value);
    void   setExposure(long value);
    long   getBrightness() const;
    long   getContrast() const;
    long   getHue() const;
    long   getSaturation() const;
    long   getSharpness() const;
    long   getGamma() const;
    long   setCaptureProperty(long property, long value);
    long   getCaptureProperty(long property, long *value) const;
    long   getCapturePropertyRange(long, long *, long *, long *, long *) const;
    const FormatsInfo *listFormats() const;
    void   negate();
    /* Filtrado */
    double getFPS() const;

private:
    /* PROPIEDADES */
    int                 width;
    int                 height;
    int                 stride;
    int                 fourcc;
    bool                connected;
    int                 physical_connection;
    FormatsInfo         *formats;
    CPCapCaptureThread  *m_Thread;
    QMutex              m_Mutex;

    void reset();

    PLATFORM_DECLS

public:
#ifdef LINUX
    void emitFrame();
#endif

#ifdef USE_QOBJECT
signals:
    void sendFrame(unsigned char *,int,int,int,int,unsigned int);
#endif
};

class CPCapCaptureThread : public QThread
{
    Q_OBJECT
public:
    CPCapCaptureThread(CPCapDevice *, QObject *parent = 0);
#ifdef Q_OS_LINUX
    void prepareTermination();
#endif

protected:
    void run();

private:
    CPCapDevice *m_Device;
    bool         m_Terminated;
};

#endif // CaptureDevice_HPP
